package com.example.factory;

import com.alibaba.fastjson.JSONObject;
import com.example.http.HttpRequestServer;
import com.example.model.FormMulit;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Classname HttpRequestServerFactory
 * @Description TODO
 * @Date 2023/4/24 20:59
 * @Created by XiongXiong
 * @Author: X.I.O
 */
public class HttpRequestServerFactory {



    public static HttpRequestServer getHttpRequestServer(HttpExchange httpExchange){
        HttpRequestServer httpRequestServer=new HttpRequestServer();
        Headers heards=httpExchange.getRequestHeaders();
        boolean isFormData=false;
        String boundary="";
        Map<String,String> maps=new HashMap<>();
        for (Map.Entry<String, List<String>> stringListEntry : heards.entrySet()) {
            String headName=stringListEntry.getKey();
            String value=stringListEntry.getValue().get(0).toString();
            if(value.contains("multipart/form-data")){
                isFormData=true;
                boundary="--"+value.substring(value.indexOf("boundary=")+"boundary=".length());
            }
            maps.put(headName,value);
        }
        //设置请求头
        httpRequestServer.setHeards(maps);
        //如果是formdata请求
        if(isFormData){
            Map<String,Object> objectMap=getFormData(httpExchange,boundary);
            if(objectMap != null){
                Map<String,Object> formData=null;
                Map<String,FormMulit> formMulit=null;
                formData=new HashMap<>();
                formMulit=new HashMap<>();
                for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
                    Object value = entry.getValue();
                    if(value instanceof FormMulit){
                        FormMulit mulit = (FormMulit) value;
                        formMulit.put(entry.getKey(),mulit);
                    }else {
                        formData.put(entry.getKey(),value);
                    }
                }
                httpRequestServer.setFormData(formData);
                httpRequestServer.setMulitMap(formMulit);
            }
        }
        //如果不是formdatq请求
        if(!isFormData){
            JSONObject json= getJSONObject(httpExchange);
            httpRequestServer.setJson(json);
        }
        Map<String,String> queryMap=getQueryMap(httpExchange);
        httpRequestServer.setQueryMap(queryMap);
        Headers headers = httpExchange.getRequestHeaders();
        //设置用户访问ip
        String ip = headers.getFirst("X-Forwarded-For");
        if (ip == null) {
            ip =httpExchange.getRemoteAddress().getHostString();
        }
        httpRequestServer.setIp(ip);
        return httpRequestServer;
    }


    private static Map<String,Object> getFormData(HttpExchange httpExchange,String boundary)  {
        try {
            // 获取请求正文流并解析
            InputStream is = httpExchange.getRequestBody();
            StringBuilder sb = new StringBuilder();
            byte[] buffer = new byte[1024];
            int bytesRead = -1;
            while ((bytesRead = is.read(buffer)) != -1) {
                sb.append(new String(buffer, 0, bytesRead,"ISO-8859-1"));
            }
            Map<String, Object> params = new HashMap<String, Object>();
            String[] parts = sb.toString().split(boundary);
            for (String part : parts) {
                if (part.contains("filename=")) {
                    String str = part.substring(part.indexOf("filename=\"") + "filename=\"".length(), part.indexOf("\r\n\r\n"));
                    String fileName=str.substring(0,str.indexOf("\""));
                    fileName=new String (fileName.getBytes ("iso-8859-1"),"UTF-8");
                    String fileType=str.substring(str.indexOf("Content-Type: ")+"Content-Type: ".length());
                    byte[] fileData = part.substring(part.indexOf("\r\n\r\n") + "\r\n\r\n".length(), part.lastIndexOf("\r\n")).getBytes("ISO-8859-1");
                    FormMulit formMulit=new FormMulit(fileData,fileName,fileType);
                    params.put(fileName,formMulit);
                } else if(part.contains("name=")) {
                    String paramName = part.substring(part.indexOf("name=\"") + "name=\"".length(), part.lastIndexOf("\""));
                    String paramValue = part.substring(part.indexOf("\r\n\r\n") + "\r\n\r\n".length(), part.lastIndexOf("\r\n"));
                    params.put(paramName,paramValue);
                }
            }
            return params;
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }



    private static JSONObject getJSONObject(HttpExchange httpExchange)  {
        InputStream is=null;
        try {
            //处理json
            is = httpExchange.getRequestBody();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            JSONObject obj=JSONObject.parseObject(sb.toString());
            return obj;
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                is.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return null;

    }


    private static Map<String,String> getQueryMap(HttpExchange httpExchange){
        Map<String, String> params = new LinkedHashMap<>();
        URI requestedUri = httpExchange.getRequestURI();
        String query = requestedUri.getRawQuery();
        if(query==null){
            return params;
        }
        String[] pairs = query.split("&");
        for (String pair : pairs) {
            int idx = pair.indexOf("=");
            String key = idx > 0 ? pair.substring(0, idx) : pair;
            String value = idx > 0 && pair.length() > idx + 1 ? pair.substring(idx + 1) : null;
            params.put(key, value);
        }
        return params;
    }



}
